//#include "qm.h"
#include <string.h>
#include <vector>
#include <iostream>

#include <cstdlib>
#include <cstdio>

using namespace std;

typedef struct  { 
    double cart[3]; 
    double nuc_charge;
    char symbol[8];
    char name[24];
}  Geom_center_t;

typedef int Geom_t;
typedef vector<Geom_center_t> Geom_data_t;

static vector<Geom_data_t*> geom_data_vec;

int Geom_create(Geom_t *geom) {
     
   for(int i = 0; i < geom_data_vec.size(); ++i) {
	if(!geom_data_vec[i]) {
	    geom_data_vec[i] = new Geom_data_t;
	    *geom = i;
	    return 0;
	}
    }
   geom_data_vec.push_back(new Geom_data_t);
   *geom = geom_data_vec.size() - 1;
   return 0;
}

int Geom_free(Geom_t geom) {
    delete geom_data_vec[geom];
    geom_data_vec[geom] = NULL;
    return 0;
}

int Geom_add(Geom_t geom, double *cart, double nuc_charge, 
	     const char *symbol, const char *name, int *index) {
    
    Geom_center_t center;
    center.symbol[0] = '\0';
    center.name[0] = '\0';
    
    for(int i = 0; i < 3; ++i) center.cart[i] = cart[i];
    center.nuc_charge = nuc_charge;
    if(symbol) strncpy(center.symbol, symbol, sizeof(center.symbol));
    if(name) strncpy(center.name, name, sizeof(center.name));

    geom_data_vec[geom]->push_back(center);
    *index = geom_data_vec[geom]->size() - 1;
  
  return 0;
}

int Geom_get_cart(Geom_t geom, int index, double *cart) {
    Geom_center_t *center = &(geom_data_vec[geom]->at(index));
    for(int i = 0; i < 3; ++i) {
	cart[i] = center->cart[i];
    }
    
    return 0;
}


int Geom_size(Geom_t geom) {
    return geom_data_vec[geom]->size();
}
   
// int Geom_write(Geom_t geom, FILE *fp) {
//     Geom_data_t *data = geom_data_vec[geom];
//     for(int i = 0; i < data->size(); ++i) {
// 	fprintf(fp, "%s(%s) %f %f %f %f\n", data->at(i).symbol, data->at(i).name,
// 		data->at(i).nuc_charge, data->at(i).cart[0], data->at(i).cart[1],
// 		data->at(i).cart[0]);
//     }

//     return 0;
// }


// int main() {
//     int handle;
//     for(int i = 0; i < 10 ; ++i) {
//     Geom_create(&handle);
//     cout << handle << endl;
//     }
//     Geom_free(5);
//     Geom_free(7);
    
//     for(int i = 0; i < 3; ++i) {
// 	Geom_create(&handle);
// 	cout << handle << endl;
//     }
//     double cart[3] = { 0.1, 0.2, 0.3};
//     int index;
//     Geom_add(2, cart, 0.0, "O", "Oxygen", &index);
//     Geom_add(2, cart, 0.0, "Ox", NULL, &index);
//     cout << index << endl;
//     Geom_get_cart(2, index, cart);

//     Geom_write(2, stdout);
//     return 0;
// }
